#!/usr/bin/python3

import time
import smbus

bus = smbus.SMBus(1)
b_len = None
LCD_ADDR = None


def write_word(addr, data):
    global b_len
    temp = data
    if b_len == 1:
        temp |= 0x08
    else:
        temp &= 0xF7
    bus.write_byte(addr, temp)


def send_command(comm):
    # Send bit7-4 firstly
    buf = comm & 0xF0
    buf |= 0x04  # RS = 0, RW = 0, EN = 1
    write_word(LCD_ADDR, buf)
    time.sleep(0.002)
    buf &= 0xFB  # Make EN = 0
    write_word(LCD_ADDR, buf)

    # Send bit3-0 secondly
    buf = (comm & 0x0F) << 4
    buf |= 0x04  # RS = 0, RW = 0, EN = 1
    write_word(LCD_ADDR, buf)
    time.sleep(0.002)
    buf &= 0xFB  # Make EN = 0
    write_word(LCD_ADDR, buf)


def send_data(data):
    # Send bit7-4 firstly
    buf = data & 0xF0
    buf |= 0x05  # RS = 1, RW = 0, EN = 1
    write_word(LCD_ADDR, buf)
    time.sleep(0.002)
    buf &= 0xFB  # Make EN = 0
    write_word(LCD_ADDR, buf)

    # Send bit3-0 secondly
    buf = (data & 0x0F) << 4
    buf |= 0x05  # RS = 1, RW = 0, EN = 1
    write_word(LCD_ADDR, buf)
    time.sleep(0.002)
    buf &= 0xFB  # Make EN = 0
    write_word(LCD_ADDR, buf)


def open_light():  # Enable the backlight
    bus.write_byte(0x27, 0x08)
    bus.close()


def clear():
    send_command(0x01)  # Clear Screen


def write(x, y, content):
    if x < 0:
        x = 0
    if x > 15:
        x = 15
    if y < 0:
        y = 0
    if y > 1:
        y = 1

    # Move cursor
    addr = 0x80 + 0x40 * y + x
    send_command(addr)

    for c in content:
        send_data(ord(c))


def init(addr=0x27, bl=1):
    global LCD_ADDR
    global b_len
    LCD_ADDR = addr
    b_len = bl
    try:
        send_command(0x33)  # Must initialize to 8-line mode at first
        time.sleep(0.005)
        send_command(0x32)  # Then initialize to 4-line mode
        time.sleep(0.005)
        send_command(0x28)  # 2 Lines & 5*7 dots
        time.sleep(0.005)
        send_command(0x0C)  # Enable display without cursor
        time.sleep(0.005)
        send_command(0x01)  # Clear Screen
        bus.write_byte(LCD_ADDR, 0x08)
    except Exception as e:
        print(e)
        return False
    else:
        return True


if __name__ == '__main__':
    init(0x27, 1)
    write(4, 0, 'Hello')
    write(7, 1, 'world!')
